@inline function Base.signbit(x::TimeSpan)
    return signbit(months(x)), signbit(nanoseconds(x))
end

function Base.sign(x::TimeSpan)
    return sign(months(x)), sign(nanoseconds(x))
end

function Base.abs(x::TimeSpan)
    if months(x) === 0
       TimeSpan(abs(nanoseconds(x)), 0)
    elseif signbit(months(x))
       TimeSpan(-nanoseconds(x), -months(x))
    else
       x
    end
end

function Base.abs2(x::TimeSpan)
    a = abs(x)
    return a*a
end

function Base.:(-)(x::TimeSpan)
    nanos = -nanoseconds(x)
    mnths = -months(x)
    return TimeSpan(nanos, mnths)
end

function Base.:(+)(x::TimeSpan, y::TimeSpan)
    nanos = nanoseconds(x) + nanoseconds(y)
    mnths = months(x) + months(y)
    return TimeSpan(nanos, mnths)
end

function Base.:(-)(x::TimeSpan, y::TimeSpan)
    nanos = nanoseconds(x) - nanoseconds(y)
    mnths = months(x) - months(y)
    return TimeSpan(nanos, mnths)
end

function Base.:(*)(x::I, y::TimeSpan) where I<:Union{Int32, Int64}
    nanos = x * nanoseconds(y)
    mnths = x * months(y)
    return TimeSpan(nanos, months)
end

function Base.:(*)(x::TimeSpan, y::I) where I<:Union{Int32, Int64}
    nanos = y * nanoseconds(x)
    mnths = x * months(y)
    return TimeSpan(nanos, months)
end

(Base.div)(x::TimeSpan, y::I) where I<:Union{Int32, Int64} = TimeSpan(div(nanoseconds(x), y), div(months(x), y))
(Base.fld)(x::TimeSpan, y::I) where I<:Union{Int32, Int64} = TimeSpan(div(nanoseconds(x), y), div(months(x), y))
(Base.cld)(x::TimeSpan, y::I) where I<:Union{Int32, Int64} = TimeSpan(div(nanoseconds(x), y), div(months(x), y))
(Base.mod)(x::TimeSpan, y::I) where I<:Union{Int32, Int64} = TimeSpan(div(nanoseconds(x), y), div(months(x), y))
(Base.rem)(x::TimeSpan, y::I) where I<:Union{Int32, Int64} = TimeSpan(div(nanoseconds(x), y), div(months(x), y))
(Base.divrem)(x::TimeSpan, y::I) where I<:Union{Int32, Int64} = div(x,y), rem(x,y)
(Base.fldmod)(x::TimeSpan, y::I) where I<:Union{Int32, Int64} = fld(x,y), mod(x,y)


for P in [:Nanosecond, :Microsecond, :Millisecond,
          :Second, :Minute, :Hour, :Day, :Week,
          :Nanoseconds, :Microseconds, :Milliseconds,
          :Seconds, :Minutes, :Hours]
    @eval begin
        Base.:(+)(x::TimeSpan, p::$P) = TimeSpan(nanoseconds(x) + nanoseconds(p), months(x))
        Base.:(+)(p::$P, x::TimeSpan) = Duration(nanoseconds(x) + nanoseconds(p), months(x))
        Base.:(-)(x::TimeSpan, p::$P) = Duration(nanoseconds(x) - nanoseconds(p), months(x))
        Base.:(-)(p::$P, x::TimeSpan) = Duration(nanoseconds(x) - nanoseconds(p), months(x))
        Base.isequal(x::TimeSpan, p::$P) = isequal(nanoseconds(x), nanoseconds(p)) && months(x) == 0
        Base.isequal(x::$P, p::TimeSpan) = isequal(nanoseconds(x), nanoseconds(p)) && months() == 0
        Base.isless(x::TimeSpan, p::$P)  = isless(nanoseconds(x), nanoseconds(p)) && months(x) <= 0
        Base.isless(x::$P, p::TimeSpan)  = isless(nanoseconds(x), nanoseconds(p)) && months(p) >= 0
    end
end


for P in [:Month, :Year,
          :Months, :Quarters, :Years, :Decades, :Centuries]
    @eval begin
        Base.:(+)(x::TimeSpan, p::$P) = TimeSpan(nanoseconds(x), months(x) + months(p))
        Base.:(+)(p::$P, x::TimeSpan) = Duration(nanoseconds(x), months(x) + months(p))
        Base.:(-)(x::TimeSpan, p::$P) = Duration(nanoseconds(x), months(x) - months(p))
        Base.:(-)(p::$P, x::TimeSpan) = Duration(nanoseconds(x), months(p) - months(x))
        Base.isequal(x::TimeSpan, p::$P) = isequal(months(x), months(p)) && nanoseconds(x) == 0
        Base.isequal(x::$P, p::TimeSpan) = isequal(months(x), months(p)) && nanoseconds(x) == 0
        Base.isless(x::TimeSpan, p::$P)  = isless(months(x), months(p)) && nanoseconds(x) <= 0
        Base.isless(x::$P, p::TimeSpan)  = isless(months(x), months(p)) && nanoseconds(p) >= 0
    end
end
